/*
-----------------------------------------------------------------------------
This source file is part of Labor3D
(Labor 3D Graphics Engine)

Copyright (c) 2009-2020 Rock Mao
* creator : Rock Mao
* created : 2009-9-21   20:29
* filename: LaborHashString.cpp
-----------------------------------------------------------------------------
*/


#include "Common/LaborHashString.h"
NAMESPACE_LABOR3D_BEGIN
void  CLHashCodeTable::string_hash(const char* str, sHashValue& hashValue)
{
	unsigned char *key     = (unsigned char *)str;
	unsigned long seed1_i  = 0x7FED7FED, seed2_i = 0xEEEEEEEE;
	unsigned long seed1_va = 0x7FED7FED, seed2_va = 0xEEEEEEEE;
	unsigned long seed1_vb = 0x7FED7FED, seed2_vb = 0xEEEEEEEE;
	int ch;
	while(*key != 0)
	{ 
		ch = toupper(*key++);

		seed1_i = m_CodeTable[HASH_INDEX][ch] ^ (seed1_i + seed2_i);
		seed2_i = ch + seed1_i + seed2_i + (seed2_i << 5) + 3; 

		seed1_va = m_CodeTable[HASH_VALUE_1][ch] ^ (seed1_va + seed2_va);
		seed2_va = ch + seed1_va + seed2_va + (seed2_va << 5) + 3; 


		seed1_vb = m_CodeTable[HASH_VALUE_2][ch] ^ (seed1_vb + seed2_vb);
		seed2_vb = ch + seed1_vb + seed2_vb + (seed2_vb << 5) + 3; 
	}
	hashValue.indexHash = seed1_i;
	hashValue.valueA    = seed1_va;
	hashValue.valueB    = seed1_vb;
}


void CLHashCodeTable::string_hashW(const wchar_t* str, sHashValue& hashValue)
{
	//unsigned char *key     = (unsigned char *)str;
	//unsigned long seed1_i  = 0x7FED7FED, seed2_i = 0xEEEEEEEE;
	//unsigned long seed1_va = 0x7FED7FED, seed2_va = 0xEEEEEEEE;
	//unsigned long seed1_vb = 0x7FED7FED, seed2_vb = 0xEEEEEEEE;
	//int ch;
	//while(*key != 0)
	//{ 
	//	ch = toupper(*key++);

	//	seed1_i = m_CodeTable[HASH_INDEX][ch] ^ (seed1_i + seed2_i);
	//	seed2_i = ch + seed1_i + seed2_i + (seed2_i << 5) + 3; 

	//	seed1_va = m_CodeTable[HASH_VALUE_1][ch] ^ (seed1_va + seed2_va);
	//	seed2_va = ch + seed1_va + seed2_va + (seed2_va << 5) + 3; 


	//	seed1_vb = m_CodeTable[HASH_VALUE_2][ch] ^ (seed1_vb + seed2_vb);
	//	seed2_vb = ch + seed1_vb + seed2_vb + (seed2_vb << 5) + 3; 
	//}
	//hashValue.indexHash = seed1_i;
	//hashValue.valueA    = seed1_va;
	//hashValue.valueB    = seed1_vb;
}


bool CLHashCodeTable::init()
{
	if(m_bCodeTableInited) return true;

	int dwSeed = 0x100001;
	int p2     = 0x2AAAAB;
	int dwHeight;
	int dwLow;
	for( int i = 0; i < 0x100; i++)
	{
		for(int j = 0; j<5; j++)
		{
			dwSeed   = (dwSeed*125+3)%p2;
			dwHeight = (dwSeed&0xFFFF)<<16;
			dwSeed   = (dwSeed*125+3)%p2;
			dwLow    = (dwSeed&0xFFFF);
			m_CodeTable[j][i] = dwHeight | dwLow ;
		}
	}

	m_bCodeTableInited = true;
	return true;
}

int  CLHashCodeTable::value(eHashCodePage codePage,int index)
{
	return table(codePage)[index];
}

CLHashCodeTable& CLHashCodeTable::singleton()
{
	static CLHashCodeTable codeTable;
	codeTable.init();
	return codeTable;
}
NAMESPACE_LABOR3D_END